package com.tfswx.ruleengine.database.service.impl;

import com.tfswx.ruleengine.compute.bean.FfItem;
import com.tfswx.ruleengine.compute.bean.GzDataDTO;
import com.tfswx.ruleengine.compute.bean.RuleInfo;
import com.tfswx.ruleengine.compute.exception.AppException;
import com.tfswx.ruleengine.compute.gzjy.RuleEngineUtil;
import com.tfswx.ruleengine.compute.util.DateUtil;
import com.tfswx.ruleengine.database.bean.TableManager;
import com.tfswx.ruleengine.database.dao.GzyqMapper;
import com.tfswx.ruleengine.database.dto.GzImportInputDTO;
import com.tfswx.ruleengine.database.dto.GzImportOutputDTO;
import com.tfswx.ruleengine.database.dto.RuleInfoListQueryParam;
import com.tfswx.ruleengine.database.service.GzyqService;
import com.tfswx.ruleengine.database.util.NetworkUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * @author Ricky
 * @date 2021/6/11
 */
@Slf4j
@Service
public class GzyqServiceImpl implements GzyqService {
    @Resource
    private GzyqMapper gzyqMapper;

    @Override
    public void execute(String sql) {
        log.info("执行SQL:{}", sql);
        gzyqMapper.execute(sql);
    }

    @Override
    public String getDatabaseId() {
        return gzyqMapper.getDatabaseId();
    }

    @Override
    public List<RuleInfo> queryRuleInfoList(RuleInfoListQueryParam ruleInfoListQueryParam) {
        return gzyqMapper.queryRuleInfoList(ruleInfoListQueryParam);
    }

    @Override
    public List<FfItem> queryFnList() {
        try {
            TableManager.createTable("ff");
        } catch (Exception e) {
            log.warn("方法表创建失败");
        }
        return gzyqMapper.queryFnList();
    }

    @Override
    public void loadFnList() {
        log.info("开始加载规则引擎方法");
        List<FfItem> ffItems = queryFnList();
        try {
            RuleEngineUtil.loadFnList(ffItems);
            log.info("规则引擎方法加载成功");
        } catch (Exception e) {
            throw new AppException("方法加载失败：" + e.getMessage(), e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public GzImportOutputDTO importGz(GzImportInputDTO gzImportInputDTO) {
        GzDataDTO gzData = RuleEngineUtil.getGzDataFromFile(gzImportInputDTO.getFile());
        return importGz(gzData);
    }

    @Override
    public GzImportOutputDTO importGz(GzDataDTO gzData) {
        String version = gzData.getVersion();
        String gzyqVersion = gzData.getGzyqVersion();
        String currGzyqVersion = RuleEngineUtil.getGzyqVersion();

        log.info("开始删除规则");
        dropTable();
        createTable();
        log.info("成功删除规则");

        int gzsl = 0;
        log.info("开始导入规则");
        List<GzDataDTO.Gzfl> gzflList = gzData.getGzflList();
        gzyqMapper.importGzflList(gzflList);
        for (GzDataDTO.Gzfl gzfl : gzflList) {
            List<GzDataDTO.Gzdy> gzdyList = gzfl.getGzdyList();
            gzsl += gzyqMapper.importGzdyList(gzdyList);
            for (GzDataDTO.Gzdy gzdy : gzdyList) {
                List<GzDataDTO.Bds> bdsList = gzdy.getBdsList();
                gzyqMapper.importBdsList(bdsList);
            }
        }
        log.info("成功导入规则");

        List<GzDataDTO.Mxstgx> mxstgxList = gzData.getMxstgxList();
        if (mxstgxList != null && !mxstgxList.isEmpty()) {
            log.info("开始导入模型实体关系");
            gzyqMapper.importMxstgxList(mxstgxList);
            log.info("成功导入模型实体关系");
        }

        int ffsl = 0;
        List<GzDataDTO.Ff> ffList = gzData.getFfList();
        if (ffList != null && !ffList.isEmpty()) {
            log.info("开始导入方法");
            ffsl = gzyqMapper.importFfList(ffList);
            log.info("成功导入方法");
        }

        GzImportOutputDTO gzImportOutputDTO = new GzImportOutputDTO();
        gzImportOutputDTO.setVersion(version);
        gzImportOutputDTO.setExptGzyqVersion(gzyqVersion);
        gzImportOutputDTO.setCurrGzyqVersion(currGzyqVersion);
        gzImportOutputDTO.setGzsl(gzsl);
        gzImportOutputDTO.setFfsl(ffsl);
        return gzImportOutputDTO;
    }

    @Override
    public void createTable() {
        TableManager.createTable();
    }

    @Override
    public void dropTable() {
        TableManager.dropTable();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void truncateTable() {
        TableManager.truncateTable();
    }

    @Override
    public GzDataDTO exportGz(String xmbm) {
        GzDataDTO gzDataDTO = new GzDataDTO();
        // 设置导出版本
        String version = DateUtil.format(new Date(), "yyyyMMddHHmmss");
        gzDataDTO.setVersion(version);
        // 设置导出引擎版本
        gzDataDTO.setGzyqVersion(RuleEngineUtil.getGzyqVersion());
        gzDataDTO.setRybm(NetworkUtil.getHost());
        gzDataDTO.setRymc(System.getProperties().getProperty("user.name"));

        // 设置项目编码
        gzDataDTO.setXmbm(xmbm);

        // 查询规则分类、定义、表达式
        List<GzDataDTO.Gzfl> gzflList = gzyqMapper.exportGzflListByXmbm(xmbm);
        gzDataDTO.setGzflList(gzflList);

        // 模型实体关系
        List<GzDataDTO.Mxstgx> mxstgxList = gzyqMapper.exportMxstgxListByXmbm(xmbm);
        gzDataDTO.setMxstgxList(mxstgxList);

        // 方法
        List<GzDataDTO.Ff> ffList = gzyqMapper.exportFfList();
        gzDataDTO.setFfList(ffList);

        return gzDataDTO;
    }
}
